package com.pointi.emoEngine;

import com.pointi.emoTools.EmotionPacket;

public class DSP_Emotion
{
	public DSP_Emotion () { }

	public double [] EmotionEngine(VoicedFrame voicedFrame, int EOC, int _LEVEL, EngineData inEngineData, int CNT)
	{
		double [] weight = inEngineData.fnWeight() ;
		double [][] xsup = inEngineData.fnXsup() ;

		// ____________________________________________________________________________________________________
		//

		if (voicedFrame.isFull())
		{
			return getResult(voicedFrame, _LEVEL, weight, xsup, CNT) ;
		}
		else if (EOC == EmotionPacket._LAST_PACKET && voicedFrame.getCurrentFrame() != 0)
		{
			return getResult(voicedFrame, _LEVEL, weight, xsup, CNT) ;
		}
		return null ;
	}

	public double [] getResult(VoicedFrame voicedFrame, int _LEVEL, double [] weight, double [][] xsup, int CNT)
	{
		double [] feature = new double [13] ;
		double [] result = new double [4] ;
		int voicedFrameCount = 0 ;
		int emotionNeutralCount = 0 ;
		int emotionAngerCount = 0 ;
		double emotionNeutral = 0 ;
		double emotionAnger = 0 ;
		double [] Pitch = voicedFrame.getPitch() ;
		double [][] MFCC = voicedFrame.getMFCC() ;
		
		int [] emotionCNT = new int[]{0, 0, 0, 0} ;
		
		// ____________________________________________________________________________________________________
		// Support Vector Machine (SVM)
		
		DSP_SVM dsp_svm = new DSP_SVM();
		DSP_Define dsp_define = new DSP_Define();
		double [] genderData = new double[4];
		
		for (int i=0; i<voicedFrame.getCurrentFrame(); i++)
		{
			if (Pitch[i] != 0)
			{
				voicedFrameCount++ ;
				feature[0] = Pitch[i];
				for (int m = 0 ; m < 12 ; m++)
				{
					feature[m+1] = MFCC[i][m] ;
				}	
				dsp_svm.SVM(feature, result, _LEVEL, weight, xsup) ;
				
				double result_sum = 0.0 ;
				calc_feat feature_stati ;
				feature_stati = dsp_define.CALC_FEAT(result, _LEVEL) ;
				for (int m = 0 ; m < _LEVEL ; m++)
				{
					result[m] -= feature_stati.min ;
					result[m] += feature_stati.range ;
					result_sum += result[m] ;
				}
				for (int m = 0 ; m < _LEVEL ; m++) { result[m] = result[m] / result_sum ; }
				emotionNeutral = result[0] + result[2] ;// result[0] : man, result[2] : woman
				emotionAnger = result[1] + result[3] ;// result[1] : man, result[3] : woman
				if (emotionNeutral > emotionAnger) { emotionNeutralCount++ ; }
				else { emotionAngerCount++ ; }
				
				int maxIDX = -1 ;
				double maxVAL = 0 ;
				for(int k=0; k<4; k++)
				{
					if(result[k] > maxVAL)
					{
						maxVAL = result[k] ;
						maxIDX = k ;
					}
				}
				emotionCNT[maxIDX]++ ;

				for (int m = 0 ; m < 4 ; m++) { genderData[m] += result[m]; }
			}
		}
		result = new double [6] ;
		if (voicedFrameCount > 3)
		{
			result[0] = (emotionNeutralCount * 100) / (double)voicedFrameCount ;
			result[1] = (emotionAngerCount * 100) / (double)voicedFrameCount ;
			result[2] = genderData[0];// * 100) / (double)voicedFrameCount ; // man Neutral
			result[3] = genderData[1];// * 100) / (double)voicedFrameCount ; // man Anger
			result[4] = genderData[2];// * 100) / (double)voicedFrameCount ; // woman Neutral
			result[5] = genderData[3];// * 100) / (double)voicedFrameCount ; // woman Anger
			
		}
		else
		{
			result[0] = 0 ;
			result[1] = 0 ;
			result[2] = 0 ;
			result[3] = 0 ;
			result[4] = 0 ;
			result[5] = 0 ;
			emotionAngerCount = 0 ;
			emotionNeutralCount = 0 ;
		}
		voicedFrame.setCount(emotionAngerCount, emotionNeutralCount) ;
		return result ;
	}
}